package com.hksj.slm.service;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import com.hksj.cbm.entity.DeviceMetadataParseInfo;
import com.hksj.cbm.mapper.DeviceMetadataParseInfoMapper;
import com.hksj.cbm.service.DeviceInstanceService;
import com.hksj.cbm.vo.SpaceModelVO;
import com.hksj.common.core.common.SpecialityModelCodeEnum;
import com.hksj.slm.mapper.LightingDeviceMapper;
import com.hksj.slm.query.LightingDeviceQuery;
import com.hksj.slm.vo.LightingDeviceVO;
import com.hksj.slm.vo.LinkLightingDetailVO;
import com.hksj.slm.vo.ModelPropertiesVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Type;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * description：照明设备服务类
 *
 * @author niexiang
 * @date 2024/08/26 15:10
 */
@Service
public class LightingDeviceService  {

    @Autowired
    private LightingDeviceMapper lightingDeviceMapper;

    @Autowired
    private DeviceInstanceService deviceInstanceService;


    /**
     * description：分页查询照明设备列表
     *
     * @param query
     * @return {@code IPage<LightingDeviceVO> }
     * @author niexiang
     * @date 2024/08/26 15:10
     */
    public IPage<LightingDeviceVO> queryLightingDeviceByPage(LightingDeviceQuery query) {
        //添加专业code
        IPage<LightingDeviceVO> page = new Page<>(query.getPageNum(), query.getPageSize());
        List<LightingDeviceVO>list=lightingDeviceMapper.queryLightingDeviceByPage(query,page);
        // 如果查询结果为空，直接返回空的分页对象
        if (!CollectionUtils.isEmpty(list)){
            // 从查询结果中提取非空路径信息
            List<String> pathList = list.stream()
                    .map(LightingDeviceVO::getPaths)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
            // 将路径信息转换为UTF8格式
            Map<String, List<SpaceModelVO>> pathNameMap = deviceInstanceService.devicePathConvertToUTF8(pathList);
            // 如果路径信息非空，则将转换后的路径名称关联到查询结果中
            if (CollUtil.isNotEmpty(pathNameMap)) {
                list.forEach(vo -> {
                    vo.setSpaceModelVOList(pathNameMap.get(vo.getPaths()));
                });
            }

            // 解析物模型
            for (LightingDeviceVO vo : list){
                Gson gson = new Gson();
                JsonObject root1 = vo.getDeriveMetadata() != null ? JsonParser.parseString(vo.getDeriveMetadata()).getAsJsonObject() : new JsonObject();
                JsonObject root2 = vo.getMetadata() != null ? JsonParser.parseString(vo.getMetadata()).getAsJsonObject() : new JsonObject();
                JsonArray properties1 = root1.has("properties") ? root1.getAsJsonArray("properties") : new JsonArray();
                JsonArray properties2 = root2.has("properties") ? root2.getAsJsonArray("properties") : new JsonArray();
                JsonArray mergedProperties = new JsonArray();
                mergedProperties.addAll(properties1);
                mergedProperties.addAll(properties2);
                // 定义 TypeToken 对象以获取 List<ModelPropertiesVO> 的 Type 信息
                Type modelListType = new TypeToken<List<ModelPropertiesVO>>() {}.getType();
                // 将 JsonArray 转换为 List<ModelPropertiesVO>
                List<ModelPropertiesVO> modelList = gson.fromJson(mergedProperties, modelListType);
                List<ModelPropertiesVO> filteredList = modelList.stream()
                        .filter(model -> !model.getId().contains("dwkg"))
                        .sorted(Comparator.comparing(ModelPropertiesVO::getId))
                        .collect(Collectors.toList());
                vo.setMetadataPropertyList(filteredList);
            }

            //查询属性信息
            List<String> deviceIds = list.stream().map(LightingDeviceVO::getDeviceId).collect(Collectors.toList());
            List<LinkLightingDetailVO> linkLightingDetailVOList = lightingDeviceMapper.queryLinkLightingDeviceDetailList(deviceIds);
            if (CollUtil.isNotEmpty(linkLightingDetailVOList)) {
                // 分组并映射到内部 Map
                Map<String, Map<String, LinkLightingDetailVO>> map = linkLightingDetailVOList.stream()
                        .collect(Collectors.groupingBy(
                                LinkLightingDetailVO::getDeviceId,  // 以 deviceId 分组
                                Collectors.toMap(
                                        LinkLightingDetailVO::getProperty,  // 使用 property 作为键
                                        Function.identity()   // 使用 DeviceMetadataParseInfo类的对象 作为值
                                )
                        ));

                // 遍历 LightingDeviceVO 对象列表，设置属性值
                for (LightingDeviceVO vo : list) {
                    Map<String, LinkLightingDetailVO> deviceMap = map.get(vo.getDeviceId());
                    if (deviceMap != null) {

                        for (ModelPropertiesVO property : vo.getMetadataPropertyList()) {
                            LinkLightingDetailVO deviceMetadataParseInfo = deviceMap.get(property.getId());
                            //非空判断
                            if(ObjectUtil.isNotNull(deviceMetadataParseInfo)) {
                                property.setSwitchStatus(deviceMetadataParseInfo.getValue());
                                //点位房间
                                property.setRoomId(deviceMetadataParseInfo.getRoomId());
                                property.setRoomName(deviceMetadataParseInfo.getRoomName());
                                property.setPointId(deviceMetadataParseInfo.getPointId());
                                property.setPointName(deviceMetadataParseInfo.getPointName());

                                //设置回路上报数据的时间
                                property.setCreateTime(deviceMetadataParseInfo.getCreateTime());

                                //设置设备上报时间
                                vo.setCreateTime(deviceMetadataParseInfo.getCreateTime());
                            }
                        }

                    }
                }
            }
        }

        return page.setRecords(list);
    }
}
